/*
 * Copyright the original author or authors.
 */
package com.derbysoft.core;

import java.io.Serializable;
import java.util.Collection;

/**
 * <code>DataAccessor</code> interface for database access
 *
 * @author snowway
 * @since 2008-7-24
 */
public interface DataAccessor {

    /**
     * load entity
     *
     * @param type entity type
     * @param id   entity id
     * @return entity
     */
    <T> T load(Class<T> type, Serializable id);


    /**
     * get entity
     *
     * @param type entity type
     * @param id   entity id
     * @return entity
     */
    <T> T get(Class<T> type, Serializable id);

    /**
     * save entity
     *
     * @param entity entity
     * @return id
     */
    Serializable save(Object entity);

    /**
     * update entity
     *
     * @param entity entity
     */
    void update(Object entity);

    /**
     * save or update an entity based on entity state
     *
     * @param entity entity
     */
    void saveOrUpdate(Object entity);


    /**
     * save or update a collection of entity
     *
     * @param entities collection of entities
     */
    void saveOrUpdateAll(Collection<?> entities);


    /**
     * delete an entity
     *
     * @param entity entity
     */
    void delete(Object entity);

    void deleteAll(Collection<?> entities);

    /**
     * refresh an entity
     *
     * @param entity entity
     */
    void refresh(Object entity);


    /**
     * batch update
     *
     * @param creator {@link QueryCreator}
     * @return affect rows
     */
    int batchUpdate(QueryCreator creator);

    /**
     * find unique entity
     *
     * @param type    query return type
     * @param creator {@link QueryCreator}
     * @return finded entity or null. if more than one entity is founded,exception will throw
     */
    <T> T findUnique(Class<T> type, QueryCreator creator);


    /**
     * find unique entity
     *
     * @param type    query return type
     * @param creator {@link CriteriaCreator}
     * @return finded entity or null. if more than one entity is founded,exception will throw
     */
    <T> T findUnique(Class<T> type, CriteriaCreator creator);


    /**
     * find entity list by hql
     *
     * @param type   query return type
     * @param hql    Hibernate HQL
     * @param values the values of param. if no param pass null.
     * @param limit  {@link Limit}
     * @param sorter {@link Sorter}
     * @return list of entity
     */
    <T> LimitedList<T> findByHql(Class<T> type, String hql, Object[] values, Limit limit, Sorter sorter);

    /**
     * find entity list by hql
     *
     * @param type   query return type
     * @param hql    Hibernate HQL
     * @param values the values of param. if no param pass null.
     * @param limit  {@link Limit}
     * @param sorter {@link Sorter}
     * @return list of entity
     */
    <T> LimitedList<T> findBySafeHql(Class<T> type, String hql, Object[] values, Limit limit, Sorter sorter);


    /**
     * find entity list by {@link QueryCreator}
     *
     * @param type    query return type
     * @param creator {@link QueryCreator}
     * @param limit   {@link Limit}
     * @param sorter  {@link Sorter}
     * @return list of entity
     */
    <T> LimitedList<T> findByQuery(Class<T> type, QueryCreator creator, Limit limit, Sorter sorter);

    /**
     * find entity list by {@link QueryCreator}
     *
     * @param type    query return type
     * @param creator {@link QueryCreator}
     * @param limit   {@link Limit}
     * @param sorter  {@link Sorter}
     * @return list of entity
     */
    <T> LimitedList<T> findBySafeQuery(Class<T> type, QueryCreator creator, Limit limit, Sorter sorter);


    /**
     * find entity list by {@link CriteriaCreator}
     *
     * @param type    query return type
     * @param creator {@link CriteriaCreator}
     * @param limit   {@link Limit}
     * @param sorter  {@link Sorter}
     * @return list of entity
     */
    <T> LimitedList<T> findByCriteria(Class<T> type, CriteriaCreator creator, Limit limit, Sorter sorter);

    /**
     * find entity list by {@link CriteriaCreator}
     *
     * @param type    query return type
     * @param creator {@link CriteriaCreator}
     * @param limit   {@link Limit}
     * @param sorter  {@link Sorter}
     * @return list of entity
     */
    <T> LimitedList<T> findBySafeCriteria(Class<T> type, CriteriaCreator creator, Limit limit, Sorter sorter);


    /**
     * find entity list by specific class
     *
     * @param type   {@link Class}
     * @param limit  {@link Limit}
     * @param sorter {@link Sorter}
     * @return list of entity
     */
    <T> LimitedList<T> findByClass(Class<T> type, Limit limit, Sorter sorter);

}